From 2f26cb24bf3e66c5c0c06c5cbe8896c36d32ff51 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 8 Nov 2003 12:17:34 +0000 Subject: [PATCH] bitkeeper revision 1.576 (3facdede5nZbIb45xqApby8e8U5CQA) xi_save_linux.c, xi_restore_linux.c, Makefile: Suspend/resume now uses zlib to reduce the state file size. --- tools/internal/Makefile | 13 +++++++++- tools/internal/xi_restore_linux.c | 36 ++++++++++++++++++---------- tools/internal/xi_save_linux.c | 40 +++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/tools/internal/Makefile b/tools/internal/Makefile index 83e23d2aa3..03a36dc277 100644 --- a/tools/internal/Makefile +++ b/tools/internal/Makefile @@ -12,7 +12,15 @@ TARGETS += xi_phys_grant xi_list xi_save_linux xi_restore_linux TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params INSTALL = $(TARGETS) xi_vifinit xi_helper -all: $(TARGETS) +all: check-for-zlib $(TARGETS) + +check-for-zlib: + @if [ ! -e /usr/include/zlib.h ]; then \ + echo "***********************************************************"; \ + echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \ + echo "***********************************************************"; \ + false; \ + fi install: all mkdir -p ../../../install/bin @@ -31,6 +39,9 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging +xi_save_linux xi_restore_linux: %: %.c $(HDRS) Makefile + $(CC) $(CFLAGS) -lz -o $@ $< + %: %.c $(HDRS) Makefile $(CC) $(CFLAGS) -o $@ $< diff --git a/tools/internal/xi_restore_linux.c b/tools/internal/xi_restore_linux.c index 8ccd145d93..fa1d3e5c55 100644 --- a/tools/internal/xi_restore_linux.c +++ b/tools/internal/xi_restore_linux.c @@ -10,6 +10,8 @@ #include "mem_defs.h" #include +#include + static char *argv0 = "internal_restore_linux"; /* A table mapping each PFN to its new MFN. */ @@ -120,10 +122,10 @@ static void unmap_pfn(void *vaddr) (void)munmap(vaddr, PAGE_SIZE); } -static int checked_read(int fd, void *buf, size_t count) +static int checked_read(gzFile fd, void *buf, size_t count) { int rc; - while ( ((rc = read(fd, buf, count)) == -1) && (errno == EINTR) ) + while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) ) continue; return rc == count; } @@ -164,8 +166,9 @@ int main(int argc, char **argv) suspend_record_t *p_srec; /* The name and descriptor of the file that we are reading from. */ - char *filename; - int fd; + char *filename; + int fd; + gzFile gfd; if ( argv[0] != NULL ) argv0 = argv[0]; @@ -183,19 +186,26 @@ int main(int argc, char **argv) return 1; } + if ( (gfd = gzdopen(fd, "rb")) == NULL ) + { + ERROR("Could not allocate decompression state for state file"); + close(fd); + return 1; + } + /* Start writing out the saved-domain record. */ - if ( !checked_read(fd, signature, 16) || + if ( !checked_read(gfd, signature, 16) || (memcmp(signature, "XenoLinuxSuspend", 16) != 0) ) { ERROR("Unrecognised state format -- no signature found"); goto out; } - if ( !checked_read(fd, name, sizeof(name)) || - !checked_read(fd, &nr_pfns, sizeof(unsigned long)) || - !checked_read(fd, &ctxt, sizeof(ctxt)) || - !checked_read(fd, shared_info, PAGE_SIZE) || - !checked_read(fd, pfn_to_mfn_frame_list, PAGE_SIZE) ) + if ( !checked_read(gfd, name, sizeof(name)) || + !checked_read(gfd, &nr_pfns, sizeof(unsigned long)) || + !checked_read(gfd, &ctxt, sizeof(ctxt)) || + !checked_read(gfd, shared_info, PAGE_SIZE) || + !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) ) { ERROR("Error when reading from state file"); goto out; @@ -222,7 +232,7 @@ int main(int argc, char **argv) pfn_to_mfn_table = calloc(1, 4 * nr_pfns); pfn_type = calloc(1, 4 * nr_pfns); - if ( !checked_read(fd, pfn_type, 4 * nr_pfns) ) + if ( !checked_read(gfd, pfn_type, 4 * nr_pfns) ) { ERROR("Error when reading from state file"); goto out; @@ -282,7 +292,7 @@ int main(int argc, char **argv) mfn = pfn_to_mfn_table[i]; - if ( !checked_read(fd, page, PAGE_SIZE) ) + if ( !checked_read(gfd, page, PAGE_SIZE) ) { ERROR("Error when reading from state file"); goto out; @@ -482,5 +492,7 @@ int main(int argc, char **argv) printf("DOM=%ld\n", dom); } + gzclose(gfd); + return !!rc; } diff --git a/tools/internal/xi_save_linux.c b/tools/internal/xi_save_linux.c index bbefaa1fb3..3170664b74 100644 --- a/tools/internal/xi_save_linux.c +++ b/tools/internal/xi_save_linux.c @@ -10,6 +10,8 @@ #include "mem_defs.h" #include +#include + static char *argv0 = "internal_save_linux"; /* A table mapping each PFN to its current MFN. */ @@ -94,10 +96,10 @@ static unsigned int get_pfn_type(unsigned long mfn) return op.u.getpageframeinfo.type; } -static int checked_write(int fd, const void *buf, size_t count) +static int checked_write(gzFile fd, void *buf, size_t count) { int rc; - while ( ((rc = write(fd, buf, count)) == -1) && (errno = EINTR) ) + while ( ((rc = gzwrite(fd, buf, count)) == -1) && (errno = EINTR) ) continue; return rc == count; } @@ -136,8 +138,9 @@ int main(int argc, char **argv) suspend_record_t *p_srec, srec; /* The name and descriptor of the file that we are writing to. */ - char *filename; - int fd; + char *filename; + int fd; + gzFile gfd; if ( argv[0] != NULL ) argv0 = argv[0]; @@ -162,6 +165,17 @@ int main(int argc, char **argv) return 1; } + /* + * Compression rate 1: we want speed over compression. We're mainly going + * for those zero pages, after all. + */ + if ( (gfd = gzdopen(fd, "wb1")) == NULL ) + { + ERROR("Could not allocate compression state for state file"); + close(fd); + return 1; + } + /* Ensure that the domain exists, and that it is stopped. */ for ( ; ; ) { @@ -314,13 +328,13 @@ int main(int argc, char **argv) /* Start writing out the saved-domain record. */ ppage = map_pfn(shared_info_frame); - if ( !checked_write(fd, "XenoLinuxSuspend", 16) || - !checked_write(fd, name, sizeof(name)) || - !checked_write(fd, &srec.nr_pfns, sizeof(unsigned long)) || - !checked_write(fd, &ctxt, sizeof(ctxt)) || - !checked_write(fd, ppage, PAGE_SIZE) || - !checked_write(fd, pfn_to_mfn_frame_list, PAGE_SIZE) || - !checked_write(fd, pfn_type, 4 * srec.nr_pfns) ) + if ( !checked_write(gfd, "XenoLinuxSuspend", 16) || + !checked_write(gfd, name, sizeof(name)) || + !checked_write(gfd, &srec.nr_pfns, sizeof(unsigned long)) || + !checked_write(gfd, &ctxt, sizeof(ctxt)) || + !checked_write(gfd, ppage, PAGE_SIZE) || + !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) || + !checked_write(gfd, pfn_type, 4 * srec.nr_pfns) ) { ERROR("Error when writing to state file"); goto out; @@ -365,7 +379,7 @@ int main(int argc, char **argv) } } - if ( !checked_write(fd, page, PAGE_SIZE) ) + if ( !checked_write(gfd, page, PAGE_SIZE) ) { ERROR("Error when writing to state file"); goto out; @@ -386,6 +400,8 @@ int main(int argc, char **argv) (void)do_dom0_op(&op); } + gzclose(gfd); + /* On error, make sure the file is deleted. */ if ( rc != 0 ) unlink(filename); -- 2.30.2